rules/*.js og registrerer sig med Nard.register(). Tryk Enter for at kaste.Al regellogik bor i én JavaScript-fil pr. variant. Filen registrerer sig hos motoren med
Nard.register({ … }) — motoren klarer resten: bræt, brikker, terninger, turskift,
fortrydelse og computer-modstander. Læg filen i rules/ og tilføj et
<script>-tag i index.html — eller indlæs den undervejs med «Indlæs regelfil».
Nard.register({
id: 'min-variant', // unik nøgle
name: 'Min variant',
description: 'Kort beskrivelse …',
checkers: 15,
board: { // info til brættet (pile + hjem-markering)
direction: { white: -1, black: 1 },
home: { white: [1, 6], black: [19, 24] }
},
setup() { // startopstillingen
return { white: { 24: 15 }, black: { 1: 15 } };
},
// Åbning: motoren ruller én terning pr. spiller
opening(r) {
if (r.white === r.black) return { reroll: true };
return { starter: r.white > r.black ? 'white' : 'black' };
// … eller med dice: [r.white, r.black] for at spille
// åbningsterningerne som det første slag (som i backgammon).
},
// Hvilke terninger slaget skal spilles med (fx 4× ved dublet)
prepareDice(d) { return d[0] === d[1] ? [d[0], d[0], d[0], d[0]] : d; },
// Alle lovlige NÆSTE træk for state.turn — tom liste = turen slutter.
// Kaldes igen efter hvert eneste træk.
nextMoves(state) {
const out = [];
// … din regellogik …
return out; // fx { from: 12, to: 15, die: 3 }
},
// Udfør et træk: mutér state, og fjern SELV terningen
// fra state.dice. Returnér { hit: 'white' } hvis en
// modstanderbrik sendes på baren (til animationen).
applyMove(state, move) {
// … flyt brikken, håndtér slag / bear-off …
return { hit: null };
},
hasWon(state, player) {
return state.off[player] >= 15 && { label: 'Sejr' };
},
// Valgfrit — gør varianten spilbar mod computeren:
evaluate(state, player) { /* højt tal = godt for player */ }
});
| Felt / hook | Beskrivelse | |
|---|---|---|
| id | ✓ | Unik nøgle (bruges ved skift af variant og ved genindlæsning) |
| name | ✓ | Navnet i variantvælgeren |
| description | – | Kort tekst under vælgeren |
| checkers | – | Brikantal pr. spiller (information) |
| board.direction | – | { white: ±1, black: ±1 } — motoren tegner flow-pile: −1 = 24→1-vejen, +1 = 1→24-vejen |
| board.home | – | { white: [fra,til], black: [fra,til] } — motoren markerer hjemfelterne på brætrammen |
| setup() | ✓ | Returnerer { white: {point: antal}, black: {…} } |
| opening(r) | – | { reroll: true } eller { starter: 'white', dice?: [a,b] } — dice spilles som det første slag. Udelades hook'en, starter hvid uden åbningskast |
| prepareDice(d) | – | Terningerne slaget skal spilles med (fx fire ens ved dublet). Standard: de to terninger |
| nextMoves(state) | ✓ | Alle lovlige næste træk [{from,to,die}]. Tom liste = turen slutter. Her styrer du selv «tvungne træk» (f.eks. at begge terninger skal bruges, hvis muligt) ved kun at tilbyde prefix-trækkene, der er tilladt |
| applyMove(state, move) | ✓ | Udfører trækket (mutér state), fjerner selv terningen fra state.dice, returnerer { hit: farve | null } |
| hasWon(state, player) | ✓ | false — eller { label: '…' }, der vises som sejrstype (fx Gammon) |
| evaluate(state, player) | – | AI-heuristik: jo højere tal, jo bedre for player. Uden den bruger computeren en naiv reserve-heuristik |
| pipCount(state, player) | – | Tal der vises i spillerpanelet |
{
points: [ , {color:'white', count:5}, … ], // index 1–24 (0 bruges ikke).
// ét felt = én farve ad gangen
bar: { white: 0, black: 0 }, // brikker på baren
off: { white: 0, black: 0 }, // brikker båret af brættet
turn: 'white' | 'black',
dice: [3, 5], // terninger der er TILBAGE i turen
rolled: [3, 5], // slaget som det blev kastet
phase: 'opening' | 'await-roll' | 'moving' | 'over'
}
'bar' eller 'off'.Nard.clone(state) giver en dyb kopi (til simulering), Nard.opp('white') giver modsat farve.rules/backgammon.js for et fuldt eksempel — inklusive den vanskeligste detalje:
reglen om at man skal bruge flest mulige terninger (og den højeste, hvis kun én kan bruges).